/* mixin */
import fieldMixin from '@src/mixins/fieldMixin';
import FormDesignMixin from '@src/mixins/formDesign';
/* api */
import * as TaskApi from '@src/api/TaskApi.ts';
import * as CustomerApi from '@src/api/CustomerApi';
import * as ProductApi from '@src/api/ProductApi';
import * as SparePart from '@src/api/SparePart';
import * as SettingTaskApi from '@src/api/SettingTaskApi';
/* util */
import * as FormUtil from '@src/component/form/util';
import _ from 'lodash';
/* components */
import RelationOptionsModal from './components/RelationOptionsModal/RelationOptionsModal.tsx';
import RelationFormsModal from '@src/modules/setting/task/taskFieldsSetting/components/RelationFormsModal';
/* enum */
import TableNameEnum from '@model/enum/TableNameEnum.ts';
import QualityMixin from '@src/mixins/qualityMixin/index.tsx'
import { FieldTypeMappingEnum, TaskFieldNameMappingEnum } from '@model/enum/FieldMappingEnum'
import i18n from '@src/locales'
/* util */
import { isNotUndefined } from '@src/util/type';
import { getRootWindow } from '@src/util/dom'
/**mode */
import {  getQualityStartTimeField, getQualityEndTimeField} from '@src/component/form/components/FormQualityInfoField/FormQualityInfoModel'

/* version control mixin */
import { 
  VersionControlProductMixin, 
  VersionControlFormMixin,
  VersionControlOtherMixin,
  VersionControlTaskMixin
} from '@src/mixins/versionControlMixin'

// 关联字段禁用的类型
const RELATION_DISABLE_FIELDS = ['attachment', 'autograph', 'separator', 'info', 'richtext', 'connector', FieldTypeMappingEnum.JsCodeBlock];


// 模块名映射
const MODE_NAME_MAP = {
  [TableNameEnum.Task]: i18n.t('task.setting.taskFieldsSetting.taskForm'),
  [TableNameEnum.TaskReceipt]: i18n.t('event.setting.serviceEventTypeSetting.flow.eventFieldsSetting.des2'),
}
// 工单表单关联字段禁用的表单类型
const TASK_RELATION_DISABLE_FIELDS = [ FieldTypeMappingEnum.RelatedCustomer, FieldTypeMappingEnum.RelatedProduct ];
// 工单表单特殊表单节点
const TASK_NODE_MODE = ['start', 'accept', 'normal'];

export default {
  name: 'task-fields-setting',
  mixins: [
    fieldMixin, 
    FormDesignMixin, 
    QualityMixin,
    VersionControlProductMixin,
    VersionControlFormMixin,
    VersionControlOtherMixin,
    VersionControlTaskMixin
  ],
  props: {
    mode: {
      type: String,
      default: TableNameEnum.Task
    },
    templateId: {
      type: String,
      default: ''
    },
    templateName: {
      type: String,
      default: ''
    },
    currentNode: {
      type: Object,
      default: () => ({}),
    },
  },
  data(){
    return {
      init: false,
      pending: false,
      visble: false,
      fields: [], // 表单字段
      hideFields: [], // 需要隐藏并且提交时需要传给后端的字段
      commonFields: [], // 公共字段
      relationField: {}, // 关联项字段
      relationOptions: { // 关联查询字段关联项数据
        customerFields: [],
        productFields: [],
        ReplacementPartFields: [],
        relationOptions: [],
      },
      relationOptionsMap: {
        relationCustomer: 'customerFields',
        relationProduct: 'productFields',
        relationReplacementPart: 'ReplacementPartFields',
        relationTask: 'relationTaskFields'
      }
    }
  },
  computed: {
    // 模块名
    modeName() {
      if(this.isHaveNodeFlowAuth && TASK_NODE_MODE.includes(this.currentNode?.type)) {
        return this.currentNode.title;
      }
     
      return MODE_NAME_MAP[this.mode];
    },
    /** 是否显示表单引用字段 */
    isShowRelationTask() {
      return this.isHaveNodeFlowAuth && TASK_NODE_MODE.includes(this.currentNode?.type);
    },
    /** 是否开启新工单流程权限 */
    isHaveNodeFlowAuth() {
      const RootWindow = getRootWindow(window)
      return RootWindow.grayAuth?.taskFlowExtend ?? false;
    },
    /**是否禁用公用字段（公共节点表单的公共字段禁止取消公用字段） */
    isDisableCommonField() {
      return this.isHaveNodeFlowAuth && this.currentNode?.isCommon == 1
    }
  },
  watch: {
    visble(val) {
      if(!val) this.$emit('success');

      if(this.isHaveNodeFlowAuth && this.currentNode?.id) {
        this.getCurrentNodeBeforeCommonFields();
      }
    }
  },
  methods: {
    initialize() {
      this.pending = true;
      const taskParams = { 
        tableName: this.mode, 
        typeId: this.templateId, 
        isFromSetting: true, 
        isShowRichText:true 
      }
      if(this.isShowRelationTask){
        taskParams.isCommonNode = Boolean(this.currentNode.isCommon)
      }

      Promise.all([
        TaskApi.getAllFields(taskParams),
        TaskApi.getCommonFieldList({ tableName: this.mode }),
        TaskApi.getSettlementRuleModule({ moduleId: this.templateId })
      ])
        .then(res => {
          this.fields = this.toFormField(res[0] || []);
          this.hideFields = []
          
          // 规则返回的数据
          let { materialVerifyEliminate, serviceIterm } = res?.[2]?.result || {};

          materialVerifyEliminate = (materialVerifyEliminate || []).map(item => {
            return {
              ...item,
              attribute: JSON.parse(item.attribute)
            }
          })
          serviceIterm = (serviceIterm || []).map(item => {
            return {
              ...item,
              attribute: JSON.parse(item.attribute)
            }
          })

          this.fields.forEach(f => {
            if (f.setting && f.setting.isEdit == 0) {
              // 保存隐藏的自定义字段
              this.hideFields.push(f)
            } else if (f.fieldName === 'serviceIterm') {
              f.setting['ruleList'] = serviceIterm
            } else if (f.fieldName === 'materialVerifyEliminate') {
              f.setting['ruleList'] = materialVerifyEliminate;
            }
          })
          // 过滤不能编辑的自定义字段 不展示（是否重复报修）
          this.fields = this.fields.filter(field => field.setting?.isEdit != 0)
          // 处理工单新建显示是否客户可见性
          if(this.mode === 'task') {
            this.fields?.forEach(item => {
              let setting = item?.setting ?? {}
              let isShow = setting?.isCustomerVisibleShow ?? false
              // 工单编号和客户默认勾选客户可见性
              if(item.fieldName === 'taskNo') isShow = true;
              if(item.fieldName === 'customer'){
                item.setting = {
                  ...setting,
                  customerOption: {...setting?.customerOption, productIsShow: true}}
              }

              item.isShow = isShow
            })
          }
          this.commonFields = res?.[1].result || [];

          this.init = true;
        })
        .finally(() => {
          this.pending = false;
        })
        .catch(e => console.log('initialize', e));     
    },
    // 打开表单设置弹窗
    open() {
      this.init = false;
      this.visble = true;
      this.initialize();
    },
    // 将后端字段转换成设计器可接受的字段
    toFormField(fields = []) {
      let sortedFields = fields.sort((a, b) => a.orderId - b.orderId);
  
      // 工单自带的 attachment 字段需要特殊处理, 提交时需要将formType还原
      sortedFields.forEach(f => {
        if(f.formType == 'attachment' && f.isSystem == 1) {
          f.formType = 'taskAttachment'
        }
      })
      
      return FormUtil.toFormField(sortedFields);
    },
    // 将字段转换成后端可接收的字段
    packToField(origin) {
      let fields = FormUtil.toField(origin);

      fields.forEach((field, index) => {
        field.templateId = this.templateId;
        field.templateName = this.templateName;
        field.tableName = this.mode;
        field.orderId = index;

        // 服务商子表单 保存时是这个字段，不是subFormFieldList 抄合同产品子表单控件的
        field.subFormFieldList && field.subFormFieldList.forEach((subField, subIndex) => {
          subField.templateId = this.templateId;
          subField.templateName = this.templateName;
          subField.tableName = this.mode;
          subField.orderId = subIndex;
        })
        
        // 还原工单表单的系统附件的formType
        if(field.formType == 'taskAttachment' && field.isSystem) {
          field.formType = 'attachment';
        }
        if(field.formType == 'quality' ) {
          if(field.setting.allowProduct != 2) {
            field.setting.approveRule ={
              multiApproveSetting: [
                {
                  state: "",
                  leader: "",
                  approves: [],
                  level: '',
                  taskTemplateId: ""
                }
              ],
              state: "",
              leader: "",
              approves: [],
              level: '',
              taskTemplateId: ""
            }
          }
        }
        // 是否升级为公共字段
        field.isUpgrade = field.isPublic > field.isCommon ? 1 : 0;

        // 新拖进来的公共字段，去掉id保存
        if(field.isDragCommon == 1) field.fieldId = field.id = null;
      })

      return fields;
    },
    /** 
    * @description 提交表单字段设置
    */
    async submit() {
      try {
        // 合并隐藏的自定义字段数据
        this.fields = this.fields.concat(this.hideFields)
        
        let fields = this.packToField(this.fields);
        // 表单字段格式校验(隐藏字段不校验)
        const isNoHiddenFields = (fields || []).filter(item => item.isHidden !== 1);
        let message = FormUtil.validate(isNoHiddenFields);
        if(!FormUtil.notification(message, this.$createElement)) return;

        
        let displayNameData = fields.map(item => item.displayName)
        let isNext = displayNameData.includes(i18n.t('common.base.sparePart')) && (displayNameData.includes(i18n.t('common.form.type.materialVerifyEliminate')) || displayNameData.includes(i18n.t('common.form.type.materialReturn')))
        if(isNext) {
          return this.$platform.notification({
            title: i18n.t('task.tip.taskFieldsTip1'),
            type: 'error'
          })
        }

        // 工单回执
        if(this.mode === 'task_receipt') {
          // 保存规则
          await this.ruleSubmit(fields);
        }

        // 工单新建的：处理客户可见性字段(客户字段需要转一下)
        if(this.mode === 'task') {
          fields = fields?.map(item => {
            if(item.fieldName === 'customer'){
              item.setting = {
                ...item?.setting,
                isCustomerVisibleShow: item.setting?.customerOption?.productIsShow ?? false,
              }
            }else {
              item.setting = {
                ...item?.setting,
                isCustomerVisibleShow: item.isShow,
              }
            }
            return item;
          })
        }

        fields.forEach(item => {
          if (item.setting.ruleList) {
            // 存储的规则删除掉,后端不要
            delete item.setting.ruleList;
          }
        })
        this.pending = true;

        // 表单可删掉入参
        let query = ''
        if(this.isShowRelationTask) {
          const isCommonNode = Boolean(this.currentNode.isCommon)
          query = `?taskTypeId=${this.templateId}&tableName=${this.mode}&isCommonNode=${isCommonNode}`
        }

        let result = await TaskApi.taskSettingSave(fields, query);

        let isSuccess = result.succ;
        this.$platform.notification({
          type: isSuccess ? 'success' : 'error',
          title: isSuccess ? i18n.t('event.setting.serviceEventTypeSetting.flow.eventFieldsSetting.tips1', {data1: this.modeName}) : i18n.t('event.setting.serviceEventTypeSetting.flow.eventFieldsSetting.tips2', {data1: this.modeName}),
          message: isSuccess ? null : result.message
        })

        if(isSuccess) {
          this.visble = false;
        }

      } catch (error) {
        console.error(error)
      }

      this.pending = false;
    },
    // 规则保存
    ruleSubmit(fields) {
      // 服务项目，物料核销 - 结算规则 - 获取配置了规则的数组
      const getRuleArr = fields.filter(item => 
        (item.fieldName === 'serviceIterm' && item.setting?.ruleList?.length) || 
        (item.fieldName === 'materialVerifyEliminate' && item.setting?.ruleList?.length)
      )
      
      
      const ruleArr = getRuleArr.map(item => {
        const { fieldName, id, formType, setting } = item;

        return (setting.ruleList || []).map(v => {
          return {
            id: v.id || '',
            moduleId: this.templateId,
            objId: id,
            objType: formType,
            objName: fieldName,
            ...v
          }
        })
      })

      let params = {
        moduleId: this.templateId,
        settlementRuleArrays: ruleArr
      }

      TaskApi.saveSettlementRule(params).then(res => {
        if (!res.success) {
          return this.$platform.notification({
            title: res.message,
            type: 'error'
          })
        }
      })
    },
    // 公共字段降级为私有字段
    transformPrivateField(field) {
      this.pending = true;

      const params = {
        templateId: this.templateId,
        commonFieldFormList: [{
          fieldName: field.fieldName,
          isUpgrade: false
        }]
      }

      TaskApi.setCommonFields(params).then(res => {
        if (res.success) {
          // 更新字段的公共字段属性
          field.isCommon = field.isPublic = 0;

          // 公共字段库删除该字段
          let index = this.commonFields.findIndex(item => item.fieldName == field.fieldName);
          this.commonFields.splice(index, 1);

          this.$platform.notification({
            title: i18n.t('common.base.tip.cancelSuccess'),
            type: 'success'
          })
        } else {
          this.$platform.alert(res.message);
        }
      })
        .finally(() => {
          this.pending = false;
        })
        .catch(err => console.warn(err));
    },
    // 修改公共字段配置
    updatePublicFieldSetting(field) {
      let fields = this.packToField([field]);

      TaskApi.updateCommonField(fields[0]).then(res => {
        if (res.success) {
          // 关闭修改控件配置弹窗
          this.$refs.formDesign.fieldSettingModal.visible = false;

          // 更新公共字段库该字段
          let index = this.commonFields.findIndex(item => item.fieldName == field.fieldName);
          this.$set(this.commonFields, index, {...field});

          this.$platform.notification({
            title: i18n.t('common.base.tip.editSuccess'),
            type: 'success'
          })
        } else {
          this.$platform.alert(res.message);
        }
      })
        .finally(() => {
          this.$refs.formDesign.fieldSettingModal.pending = false;
        })
        .catch(err => console.warn(err));
    },
    /** 
    * @description 获取客户关联查询字段关联项数据
    */
    getCustomerFields() {
      CustomerApi.getCustomerFields({ isFromSetting: false })
        .then(res => {
          if (res.succ) {
            // 过滤自定义字段且非禁用类型
            let fields = res.data.filter(field => field.isSystem == 0 && RELATION_DISABLE_FIELDS.indexOf(field.formType) == -1);

            fields.unshift({
              'fieldId':'serialNumber',
              'tableName':'customer',
              'fieldName':'serialNumber',
              'displayName': i18n.t('common.form.type.customerNo'),
              'isSystem':'0',
              'isSearch':'1',
              'isAppShow':'0',
              'formType':'text'
            }, {
              'fieldId':'tags',
              'tableName':'customer',
              'fieldName':'tags',
              'displayName': i18n.t('common.base.serviceDepartment'),
              'isSystem':'0',
              'isSearch':'1',
              'isAppShow':'0',
              'formType':'selectMulti'
            }, {
              'fieldId':'customerManager',
              'tableName':'customer',
              'fieldName':'customerManager',
              'displayName': i18n.t('common.form.preview.qualityField.label11'),
              'isSystem':'0',
              'isSearch':'1',
              'isAppShow':'0',
              'formType':'text'
            })
            
            this.relationOptions.customerFields = fields;
            
          }
        })
        .catch(err => console.warn(err));
    },
    getPartField() {
      SparePart.getPartField()
        .then(res => {
          if (res) {  // 过滤自定义字段且非禁用类型
            this.relationOptions.ReplacementPartFields = res.data;
          }
        })
        .catch(err => console.warn(err));
    },
    /** 
    * @description 获取产品关联查询字段关联项数据
    */
    getProductFields() {
      ProductApi.getProductFields({ isFromSetting: false })
        .then(res => {
          if (res.succ) {
            // 过滤自定义字段且非禁用类型
            let fields = res.data.filter(field => (field.isSystem == 0 && RELATION_DISABLE_FIELDS.indexOf(field.formType) == -1) || field.fieldName == 'qualityInfo');
            // 插入质保开始日期，质保结束日期
            const targetIndex = fields.findIndex(f => f.fieldName === 'qualityInfo');

            if (targetIndex !== -1) {
              const fieldList =[getQualityStartTimeField(fields[targetIndex]), getQualityEndTimeField(fields[targetIndex])]
              // 删除当前节点
              fields.splice(targetIndex, 1);
              // 插入到 targetIndex 后面
              fields.splice(targetIndex, 0, ...fieldList);
            }
            // 过滤不能编辑的自定义字段 不展示（是否重复报修）
            fields = fields.filter(field => field.setting?.isEdit != 0)

            fields.unshift({
              'fieldId':'serialNumber',
              'tableName':'customer',
              'fieldName':'serialNumber',
              'displayName': i18n.t('common.form.type.productNo'),
              'isSystem':'0',
              'isSearch':'1',
              'isAppShow':'1',
              'formType':'text'
            }, {
              'fieldId':'type',
              'tableName':'customer',
              'fieldName':'type',
              'displayName': i18n.t('common.base.productType'),
              'isSystem':'0',
              'isSearch':'1',
              'isAppShow':'1',
              'formType':'select'
            })

            this.relationOptions.productFields = fields;
          }
        })
        .catch(err => console.warn(err));
    },
    /** 
    * @description 打开关联项设置弹窗
    * 从左侧基础控件拖入客户关联字段或者产品关联字段时打开弹窗
    */
    openRelatedOptionsDialog(field) {
      this.relationField = field;
      
      // 关联项字段列表
      let relationTypeOption = this.relationOptionsMap[field.formType];
      let relationOptions = this.relationOptions[relationTypeOption];
      
      const fieldNameByVersionShowMap = {
        // 产品类型
        // type: this._isShowProductType,
        // 产品模板
        productTemplate: this._isShowProductTemplate,
        // 质保开始时间
        qualityInfoStartTime: this._isShowProductQuality,
        // 质保结束时间
        qualityInfoEndTime: this._isShowProductQuality,
        // 质保状态
        qualityInfoStatus: this._isShowProductQuality
      }
      relationOptions = relationOptions.filter(item => {
        
        const isShow = fieldNameByVersionShowMap[item?.fieldName]
        if (isNotUndefined(isShow)) {
          return isShow
        }
        
        return true;
        
      })?.filter(item => !['logistics'].includes(item.formType)) ?? [] // 关联字段过滤物流控件
      
      let isCustomer = field.formType;
      this.$refs.relationOptionsModal.open(relationOptions, isCustomer);
    },
    /** 获取工单表单引用表单字段 */
    getSelectedRelationTaskItem() {
      const selectedRelationTask = this.fields.filter(f => f.formType === TaskFieldNameMappingEnum.RelationTask);
      return selectedRelationTask?.map(f=>f.setting.fieldName) || [];
    },
    /**打开表单关联字段 */
    openRelationFormModal(field) {
      this.relationField = field;
      // 关联项字段列表
      let relationTypeOption = this.relationOptionsMap[field.formType];
      let relationOptions = this.relationOptions[relationTypeOption];
      this.$refs.relationFormModal.open(relationOptions, this.getSelectedRelationTaskItem());
    },
    /** 
    * @description 关联项设置成功
    */
    relationOptionsConfirm(options = []) {
      const  associationFormFieldName = options.map(item=>item.fieldName);

      // 表单中已存在的字段
      const existingFields = new Set(this.fields.filter(f => f.formType === TaskFieldNameMappingEnum.RelationTask).map(item => item?.setting?.fieldName));

      // 筛选出新增加的字段
      const addedFields = options.filter(f => !existingFields.has(f.fieldName));

      // 筛选出已删除的字段
      const deletedFields = this.fields.filter(field => {
        return field.formType === TaskFieldNameMappingEnum.RelationTask && !associationFormFieldName.includes(field?.setting?.fieldName);
      }).map(f => f?.setting?.fieldName);

      // 更新 this.fields，保留未删除的字段
      this.fields = this.fields.filter(field => !(field.formType === TaskFieldNameMappingEnum.RelationTask && deletedFields.includes(field?.setting?.fieldName)));

      for (let index = 0; index < addedFields.length; index++) {
        const setting = addedFields[index];
        const field = _.cloneDeep(this.relationField);
        
        // 设置该关联查询字段的标题为关联项标题
        field.name = setting.displayName;

        // 删除setting多余字段
        delete setting.displayName;
        field.setting = setting;
        if(field.formType == 'relationReplacementPart'){
          field.placeHolder = i18n.t('common.form.type.relateSparePart')
        }
        // 加延时异步是因为form-design的insertField方法更新value异步会导致选择多个关联项时只能插入一个
        setTimeout(() => {
          this.$refs.formDesign.immediateInsert(field, null, true);
        }, 0)
      }
    },
    /** 获取当前节点之前的基础字段 */ 
    async getCurrentNodeBeforeCommonFields() {
      try {
        const params = {
          taskTypeId: this.templateId,
          currentNodeId: this.currentNode.id
        }
        const { success, result = [] } = await SettingTaskApi.getCurrentNodeBeforeCommonFields(params);
        if (success) {
          this.relationOptions.relationTaskFields = result.filter(f=>!TASK_RELATION_DISABLE_FIELDS.includes(f.formType))
        }
      } catch (error) {
        console.log(error);
      }
    }
  },
  mounted() {
    this.$eventBus.$on('task_form_design_relation_options_set', this.openRelatedOptionsDialog);
    this.$eventBus.$on('task_form_design_relation_form_set', this.openRelationFormModal);

    // 获取客户和产品关联字段关联项数据
    this.getCustomerFields();
    this.getProductFields();
    this.getPartField();
  },
  beforeDestroy() {
    this.$eventBus.$off('task_form_design_relation_options_set', this.openRelatedOptionsDialog);
    this.$eventBus.$off('task_form_design_relation_form_set', this.openRelationFormModal);
  },
  components: {
    RelationOptionsModal,
    RelationFormsModal
  }
}